﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Runtime.Serialization;
using System.Collections;
using System.ComponentModel;
using System.Collections.Specialized;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC
{
    public class StateFactory
    {
        [MethodVisible]
        public static CommandToPerform CreateHealingRateStateCommand(params IdentifierAndValue[] identifiersAndValues)
        {
            CommandToPerform cmd = new CommandToPerform()
            {
                Arguments = new PropertyData(identifiersAndValues),
                PerformMethod = new Method(typeof(StateFactory).FullName, "HealState")
            };
            return cmd;
        }

        [MethodVisible]
        public static CommandToPerform CreateAttackStateCommand(long source, long target, params IdentifierAndValue[] identifiersAndValues)
        {
            return CommandFactory.CreateAttack(source, target);
        }

        [MethodVisible]
        public static State CreateBeingAttackedState()
        {
            State state = new State()
            {
                StateName = "BeingAttackedState"
            };

            return state;
        }

        [MethodVisible]
        public static State CreateBasicAttackState() 
        {
            State state = new State()
            {
                StateName = "BasicAttackState"
            };

            return state;
        }

        [MethodVisible]
        public static State CreateBasicHealingState(int healAmount, int mpAmount, int rescheduleFrequency)
        {
            State state = new State()
            {
                BaseStateAction = StateFactory.CreateHealingRateStateCommand(),
                BaseRescheduleFrequency = rescheduleFrequency,
                StateName = "BasicHealingState",
                ThingProperties = new PropertyData(new IdentifierAndValue("HealAmount", healAmount),
                                                   new IdentifierAndValue("MovementAmount", mpAmount))
            };

            return state;
        }

        [MethodVisible]
        public static State CreateFatigueState(int adjustHealAmount)
        {
            CommandToPerform cmdFatigue = StateFactory.CreateFatigueStateCommand();

            State state2 = new State()
            {
                StateName = "FatigueState",
                ThingProperties = new PropertyData(new IdentifierAndValue("AdjustHealAmount", adjustHealAmount))
            };

            state2.ModifyExecutingState.Add("BasicHealingState", cmdFatigue);

            return state2;
        }

        [MethodVisible]
        public static CommandToPerform CreateFatigueStateCommand(params IdentifierAndValue[] identifiersAndValues)
        {
            CommandToPerform cmd = new CommandToPerform()
            {
                Arguments = new PropertyData(identifiersAndValues),
                PerformMethod = new Method(typeof(StateFactory).FullName, "FatigueState")
            };
            return cmd;
        }

        [MethodVisible]
        public static List<PerceivedEventAndAudience> HealState(CommandToPerform command, IGameThing source, IGameThing target, PropertyData args, PropertyData modifyingArguments)
        {
            int healAmount = args.GetArgument<int>("HealAmount", 1);
            int mpAmount = args.GetArgument<int>("MovementAmount", 1);
            GameChar gameThing = source as GameChar;

            if (gameThing != null)
            {
                gameThing.ChangesAndActions.ModificationsAndRequisites.Enqueue(new Modification() { Change = CommandFactory.AddOrSubtractFromProperty("HitPoints", healAmount) });
                gameThing.ChangesAndActions.ModificationsAndRequisites.Enqueue(new Modification() { Change = CommandFactory.AddOrSubtractFromProperty("MovementPoints", mpAmount) });
            }

            return null;
        }

        [MethodVisible]
        public static List<PerceivedEventAndAudience> FatigueState(CommandToPerform command, IGameThing source, IGameThing target, PropertyData args, PropertyData modifyingArguments)
        {
            int adjustHeal = modifyingArguments.GetArgument<int>("AdjustHealAmount", -1);
            GameChar gameThing = source as GameChar;

            if (gameThing != null)
            {
                IdentifierAndValue val = args.GetArgumentReference("HealAmount");

                if (val.Value != null)
                    val.Value = Convert.ToInt32(val.Value) + adjustHeal;
            }

            return null;
        }
    }
}
